package com.happy3w.file.server.service;

import com.happy3w.file.server.entity.FileEntity;
import com.happy3w.file.server.repository.FileRepository;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

@Service
public class FileService {
    private final String baseDir;
    private final FileRepository fileRepository;

    public FileService(@Value("${file-server.base-dir}") String baseDir, FileRepository fileRepository) {
        this.fileRepository = fileRepository;
        this.baseDir = baseDir.endsWith("/") ? baseDir : baseDir + "/";
    }

    private static final DateTimeFormatter dateFormater = DateTimeFormatter.ofPattern("yyyy/MM/dd");
    private String newTargetFileName(String uuid, String orgFileName) {
        String tail = orgFileName.substring(orgFileName.lastIndexOf("."));
        return MessageFormat.format("{0}/{1}{2}",
                dateFormater.format(LocalDateTime.now()),
                uuid,
                tail);
    }

public Mono<FileEntity> uploadFile(FilePart file, String subDir) throws IOException {
    String orgFileName = file.filename();
    String uuid = UUID.randomUUID().toString();
    String fileName = newTargetFileName(uuid, orgFileName);
    FileEntity fileEntity = FileEntity.builder()
            .name(orgFileName)
            .cluster(subDir)
            .path(fileName)
            .uuid(uuid)
            .build();

    String absPath = toRealPath(subDir, fileEntity);
    Path filePath = Paths.get(absPath);
    Files.createDirectories(filePath.getParent());
    return file.transferTo(filePath)
            .then(Mono.fromCallable(() -> fileRepository.save(fileEntity)));
}

    public FileEntity findFile(String uuid) {
        return fileRepository.findByUuid(uuid);
    }

    public String toRealPath(String subDir, FileEntity fileEntity) {
        return MessageFormat.format("{0}{1}{2}",
                baseDir, subDir.endsWith("/") ? subDir : subDir + "/", fileEntity.getPath());
    }
}
